/**
 * 
 */
package com.netscenery.yang.model;



import org.jdom2.Attribute;
import org.jdom2.Element;

import com.netscenery.util.ErrTag;
import com.netscenery.util.ILinkData;
import com.netscenery.util.Unicode;
import com.netscenery.util.XMLTag;
import com.netscenery.yang.YangStatement;
import com.netscenery.yang.designer.MapInfo;

/**
 * @author llly
 *
 */
public class Revision extends ModelElement implements ILinkData {
	
	
	private String description;
	private String reference;
	
	public Revision(){
		super();
	}
	
	public Revision(String name){
		if (!checkName(name))
		{
			return;
		}
		this.name = name;
	}

	public String getName() {
		return name;
	}



	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getReference() {
		return reference;
	}

	public void setReference(String reference) {
		this.reference = reference;
	}
	
	public boolean checkName(String name){
		return Revision.checkRevisionDate(name);
	}
	
	public static boolean checkRevisionDate(String date){
		String regex = "^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]" +
				"|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)" +
				"|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]" +
				"|[2468][048]|[13579][26])00)-02-29)$";
		return date.matches(regex);
	}
	
	/**
	 * ��֤revision����ȷ��
	 * @return
	 */
	public Validator validate(){
		Validator validator = new Validator();
		/*
		 * ���������ƣ��ұ�����YYYY-MM-DD����ʽ
		 */
		if (isNullString(this.name)){
			validator.setIsValid(false);
			validator.addMsg(new Message(this, ErrTag.ERROR,"the name is mandatory."));
		}
		else {
			if(! checkName(name)){
				validator.setIsValid(false);
				validator.addMsg(new Message(this, ErrTag.ERROR,"invalid name, \"YYYY-MM-DD\" is expected."));
			}
		}
		
		if (!isNullString(this.description)){
			if (Unicode.containChinese(this.description)){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,"description",ErrorCode.INVALID_CHARACTER));
			}
		}
		
		if (!isNullString(this.reference)){
			if (Unicode.containChinese(this.reference)){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,"reference",ErrorCode.INVALID_CHARACTER));
			}
		}
		
		Validator sValidator = super.validate();
		validator.copy(sValidator);
		return validator;
		
	}
	/**
	 * �ж�ĳ���ֶ��ǲ��Ǳ����
	 * @param field
	 * @return
	 */
	public boolean isFieldMandatory(String field){

		if (this.hasField(field)){
			if ("name".equals(field)){
				return true;
			}
			else{
				return false;
			}
		}
		
		return false;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.ModelElement#toYang()
	 */
	@Override
	public YangStatement toYang() {
		YangStatement revision = new YangStatement(YangStatement.YANG_STATEMENT_REVISION);
		revision.setArgument(name);
		
		if (null != this.description){
			YangStatement descr = new YangStatement(YangStatement.YANG_STATEMENT_DESCRIPTION);
			descr.setArgument(description);	
			revision.addChild(descr);
		}
		
		if (null != this.reference){
			YangStatement refer = new YangStatement(YangStatement.YANG_STATEMENT_REFERENCE);
			refer.setArgument(reference);
			revision.addChild(refer);
		}
		
		return revision;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.ModelElement#toXML()
	 */
	@Override
	public Element toXML() {
		Element revision = new Element(XMLTag.XML_TAG_REVISION);
		Element name = new Element("name");
		name.setText(this.name);
		revision.addContent(name);
		if (null != this.description){
			Element desc = new Element(XMLTag.XML_TAG_DESCRIPTION);
			desc.setText(description);
			revision.addContent(desc);
		}
		
		if (null != this.reference){
			Element ref = new Element(XMLTag.XML_TAG_REFERENCE);
			ref.setText(reference);
			revision.addContent(ref);
		}
		return revision;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.ModelElement#readXML(org.jdom2.Element)
	 */
	@Override
	public int readXML(Element element) {
		if (null == element){
			return MODELELEMENT_OK;
		}
		
		if (element.getName().equals(XMLTag.XML_TAG_DESCRIPTION)){
			if (null == this.getDescription()){
				this.setDescription(element.getText());
			}
			else {
				return MODELELEMENT_DUPLICATE;
			}
			
		}
		else if (element.getName().equals(XMLTag.XML_TAG_REFERENCE)){
			if (null == this.getReference()){
				this.setReference(element.getText());
			}
			else {
				return MODELELEMENT_DUPLICATE;
			}
			
		}
		else if (element.getName().equals(XMLTag.XML_TAG_NAME)){
			return MODELELEMENT_OK;
			
		}		
		else {
			return MODELELEMENT_FAIL;
		}
		
		return MODELELEMENT_OK;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.ModelElement#readYANG(com.netscenery.modeldesigner.util.YangStatement)
	 */
	@Override
	public int readYANG(YangStatement statement) {
		
		if (null == statement){
			return MODELELEMENT_OK;
		}
		
		if (statement.getKeyword().equals(YangStatement.YANG_STATEMENT_DESCRIPTION)){
			if (null == this.getDescription()){
				this.setDescription(statement.getArgument());
			}
			else {
				return MODELELEMENT_DUPLICATE;
			}
			
		}
		else if (statement.getKeyword().equals(YangStatement.YANG_STATEMENT_REFERENCE)){
			if (null == this.getReference()){
				this.setReference(statement.getArgument());
			}
			else {
				return MODELELEMENT_DUPLICATE;
			}
			
		}
		else {
			return MODELELEMENT_FAIL;
		}
		
		return MODELELEMENT_OK;
	}

	public  MapInfo getMapInfo() throws SecurityException, NoSuchMethodException {
		// TODO Auto-generated method stub
		return null;
	}

	
	@Override
	public boolean equals(Object data) {
		if (null == data){
			return false;
		}
		
		Revision rev = (Revision)data;
		if (this.getName().equals(rev.getName())){
			return true;
		}
		else {
			return false;
		}
		
	}

	@Override
	public int compare(Object data) {
		if (null == data){
			return 1;
		}
		
		Revision rev = (Revision)data;
		if (this.getName().compareTo(rev.getName()) > 0){
			return 1;
		}
		else if (this.getName().compareTo(rev.getName()) < 0){
			return -1;
		}
		return 0;

	}

	@Override
	public Element toYin() {
		Element revision = new Element(YangStatement.YANG_STATEMENT_REVISION,env.getNs());
		Attribute date = new Attribute("date",this.name);
		revision.setAttribute(date);
		if (!isNullString(this.getDescription())){
			Element descr = new Element(YangStatement.YANG_STATEMENT_DESCRIPTION,env.getNs());
			Element text = new Element(XMLTag.XML_TAG_TEXT,env.getNs());
			text.setText(this.description);
			descr.addContent(text);
			revision.addContent(descr);
			
		}
		
		if (!isNullString(this.getReference())){
			Element ref = new Element(YangStatement.YANG_STATEMENT_REFERENCE,env.getNs());
			Element text = new Element(XMLTag.XML_TAG_TEXT,env.getNs());
			text.setText(this.reference);
			ref.addContent(text);
			revision.addContent(ref);
		}
		
		return revision;
	}

	@Override
	public int readYin(Element statement) throws ModelException {
		
		if (null == statement){
			return MODELELEMENT_OK;
		}
		
		if (statement.getName().equals(YangStatement.YANG_STATEMENT_DESCRIPTION)){
			String value = statement.getChildText(XMLTag.XML_TAG_TEXT, env.getNs());
			if (null == this.getDescription()){
				this.setDescription(value);
			}
			else {
				return MODELELEMENT_DUPLICATE;
			}
			
		}
		else if (statement.getName().equals(YangStatement.YANG_STATEMENT_REFERENCE)){
			String value = statement.getChildText(XMLTag.XML_TAG_TEXT, env.getNs());
			if (null == this.getReference()){
				this.setReference(value);
			}
			else {
				return MODELELEMENT_DUPLICATE;
			}
			
		}
		else {
			return MODELELEMENT_FAIL;
		}
		
		return MODELELEMENT_OK;
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		
	}


}
